package cn.maihe.elg.operation.web.invoice;

import cn.maihe.elg.operation.exception.ErrorCode;
import cn.maihe.elg.operation.exception.SystemRuntimeException;
import cn.maihe.elg.operation.model.enums.InvoiceFlagEnum;
import cn.maihe.elg.operation.model.enums.InvoiceSetFlagEnum;
import cn.maihe.elg.operation.model.enums.InvoiceStatusEnum;
import cn.maihe.elg.operation.model.enums.UserType;
import cn.maihe.elg.operation.model.vo.invoice.InvoiceReportQueryVO;
import cn.maihe.elg.operation.model.vo.invoice.InvoiceVO;
import cn.maihe.elg.operation.model.vo.order.AcceptOrderDetailVO;
import cn.maihe.elg.operation.model.vo.order.ListAcceptOrderDO;
import cn.maihe.elg.operation.model.vo.order.ListAcceptOrderVO;
import cn.maihe.elg.operation.repository.entity.*;
import cn.maihe.elg.operation.security.model.UserContext;
import cn.maihe.elg.operation.service.business.BidCustomerService;
import cn.maihe.elg.operation.service.business.OrgInstitutionSetService;
import cn.maihe.elg.operation.service.business.ProjectInfoService;
import cn.maihe.elg.operation.service.invoice.InvoiceInfoService;
import cn.maihe.elg.operation.service.invoice.SellerInfoService;
import cn.maihe.elg.operation.service.order.AcceptOrderInfoService;
import cn.maihe.elg.operation.supports.invoice.nuonuo.InvoiceHelper;
import cn.maihe.elg.operation.utils.*;
import cn.maihe.framework.starter.base.sql.PageBo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description 发票信息controller
 * @Author caixh
 * @Date 2021/4/14.
 */
@Api(value = "发票管理", tags = "发票管理")
@RestController
@RequestMapping("/api")
@Slf4j
public class InvoiceController {
    @Resource
    private InvoiceInfoService invoiceInfoService;
    @Autowired
    private DownloadExcelTool downloadExcelTool;
    @Resource
    private AcceptOrderInfoService acceptOrderInfoService;
    @Resource
    private OrgInstitutionSetService orgInstitutionSetService;
    @Resource
    private SellerInfoService sellerInfoService;
    @Resource
    private BidCustomerService bidCustomerService;
    @Resource
    private InvoiceHelper invoiceHelper;
    @Resource
    private ProjectInfoService projectInfoService;

    @ApiOperation(value = "分页查询发票信息", notes = "根据发票信息类型、机构编码、机构名称 分页查询")
    @RequestMapping(value = "/invoices", method = RequestMethod.GET)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNo", value = "页数", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页大小", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "invoiceFlag", value = "开票标志", dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "orderNo", value = "订单编号", dataType = "String", paramType = "query"),
//            @ApiImplicitParam(name = "Name", value = "开票信息名称", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "guaranteeTimeRange", value = "创建时间（startDate,endDate）", dataType = "String", paramType = "query")
    })
    public PageBo<AcceptOrderDetailVO> pageList(int pageNo, int pageSize, String guaranteeTimeRange, ListAcceptOrderVO vo) {
        //登录机构过滤
        UserContext uc = UserContextUtil.getUserContext();
        if (UserType.GENERAL.getType() != uc.getUserType()) {
            vo.setOrgId(uc.getOrgId());
        }
        vo.setInvoiceQuery("invoice");
        return acceptOrderInfoService.selectPageBySql(pageNo, pageSize, vo);
    }

    @ApiOperation(value = "获取开票信息", notes = "根据订单信息id获取开票信息")
    @ApiImplicitParam(name = "id", value = "订单信息id", dataType = "long", paramType = "path", required = true)
    @RequestMapping(value = "/invoice/{id}", method = RequestMethod.GET)
    public Map get(@PathVariable Long id) {
        AcceptOrderInfoDO acceptOrderInfoDO = acceptOrderInfoService.selectById(id);
        if (acceptOrderInfoDO == null) {
            throw new SystemRuntimeException(ErrorCode.NOTEXISTS, "订单信息id");
        }
        UserContext uc = UserContextUtil.getUserContext();
        if (UserType.GENERAL.getType() != uc.getUserType()) {
            OrgInstitutionSetDO orgInstitutionSetDO = orgInstitutionSetService.selectOne(OrgInstitutionSetDOCondition.builder()
                    .andOrgIdEq(uc.getOrgId()).andInstitutionIdEq(acceptOrderInfoDO.getInstitutionId()).build());
            if (orgInstitutionSetDO == null || orgInstitutionSetDO.getInvoiceFlag() == InvoiceSetFlagEnum.SELF.getValue()) {
                throw new SystemRuntimeException(ErrorCode.BSMOI001, "");
            }

            SellerInfoDO sellerInfoDO = sellerInfoService.selectOne(SellerInfoDOCondition.builder().andOrgIdEq(uc.getOrgId()).build());
            if (sellerInfoDO == null || StringUtils.isEmpty(sellerInfoDO.getToken())) {
                throw new SystemRuntimeException(ErrorCode.BSMOI002, "");
            }

            BidCustomerDO bidCustomerDO = bidCustomerService.selectById(acceptOrderInfoDO.getBidCustomerId());
            Map result = new HashMap();
            result.put("order", acceptOrderInfoDO);
            result.put("invoiceFlag", orgInstitutionSetDO.getInvoiceFlag());
            result.put("seller", sellerInfoDO);
            result.put("customer", bidCustomerDO);
            return result;
        } else {
            throw new SystemRuntimeException(ErrorCode.AUTHERROR, "");
        }

    }


    @ApiOperation(value = "开票", notes = "开票")
    @RequestMapping(value = "/invoice", method = RequestMethod.POST)
    public void invoice(@Validated @RequestBody InvoiceVO invoiceVO) {
        AcceptOrderInfoDO acceptOrderInfoDO = acceptOrderInfoService.selectById(invoiceVO.getOrderId());
        SellerInfoDO sellerInfoDO = sellerInfoService.selectById(invoiceVO.getSellerId());
        BidCustomerDO bidCustomerDO = bidCustomerService.selectById(acceptOrderInfoDO.getBidCustomerId());
        ProjectInfoDO projectInfo = projectInfoService.selectById(acceptOrderInfoDO.getProjectId());

        InvoiceInfoDO invoiceInfoDO = new InvoiceInfoDO();
        invoiceInfoDO.setId(IdGenerate.getId());
        invoiceInfoDO.setAcceptOrderNos(acceptOrderInfoDO.getAcceptOrderNo());
        invoiceInfoDO.setCenterId(acceptOrderInfoDO.getCenterId());
        invoiceInfoDO.setOrgId(acceptOrderInfoDO.getOrgId());
        invoiceInfoDO.setInvoiceTitle(bidCustomerDO.getBidderName());
        invoiceInfoDO.setInvoiceType(1);
//        invoiceInfoDO.setInvoiceNo();
        invoiceInfoDO.setCustomerName(bidCustomerDO.getBidderName());
        invoiceInfoDO.setCustomerCreditCode(bidCustomerDO.getBidderCreditCode());
        invoiceInfoDO.setCustomerBankCode(bidCustomerDO.getLicenseAccount());
        invoiceInfoDO.setCustomerOpneBank(bidCustomerDO.getLicenseBank());
        invoiceInfoDO.setCustomerAddress(bidCustomerDO.getBidderRegAddress());
//        invoiceInfoDO.setCustomerPhone(bidCustomerDO.getBidderContactTel());
        //发票购买方电话若有开票座机号则取该值，其他默认取客户经办人联系电话
        String customerPhone = StringUtils.isNotBlank(bidCustomerDO.getComTelNum()) ? bidCustomerDO.getComTelNum() : bidCustomerDO.getBidderContactTel();
        invoiceInfoDO.setCustomerPhone(customerPhone);

        invoiceInfoDO.setCustomerContactName(bidCustomerDO.getBidderContactName());
        invoiceInfoDO.setCustomerContactTel(bidCustomerDO.getBidderContactTel());
        //邮箱格式错误 会导致开票失败
        invoiceInfoDO.setCustomerContactEamil(bidCustomerDO.getBidderEamil());
        invoiceInfoDO.setCustomerContactAddress(bidCustomerDO.getBidderRegAddress());
        invoiceInfoDO.setAmount(acceptOrderInfoDO.getGuaranteeFee());
        invoiceInfoDO.setAmountOfChinaese(CurrencyUpperUtil.fenToCurrencyUpper(acceptOrderInfoDO.getGuaranteeFee()));
        invoiceInfoDO.setSellerName(sellerInfoDO.getSellerName());
        invoiceInfoDO.setSellerCreditCode(sellerInfoDO.getSellerCreditCode());
        invoiceInfoDO.setSellerBankCode(sellerInfoDO.getSellerBankCode());
        invoiceInfoDO.setSellerOpenBank(sellerInfoDO.getSellerOpenBank());
        invoiceInfoDO.setSellerAddress(sellerInfoDO.getSellerAddress());
        invoiceInfoDO.setSellerPhone(sellerInfoDO.getSellerPhone());
        invoiceInfoDO.setHandler(sellerInfoDO.getHandler());
        invoiceInfoDO.setInvoiceRemark("电子保函");
        invoiceInfoDO.setStatus(InvoiceStatusEnum.PROSESS.getValue());
        invoiceInfoDO.setOrderCount(1);
        acceptOrderInfoDO.setInvoiceId(invoiceInfoDO.getId());
        acceptOrderInfoDO.setInvoiceFlag(InvoiceFlagEnum.INVOICED.getValue());
        //调用开票信息
        String invoiceSerialNum = invoiceHelper.requestBillingNew(acceptOrderInfoDO.getAcceptOrderNo(),invoiceInfoDO,projectInfo.getProjectName());
        invoiceInfoDO.setSerialNo(invoiceSerialNum);
        invoiceInfoService.save(invoiceInfoDO, acceptOrderInfoDO);

    }


    @ApiOperation(value = "查询发票订单信息", notes = "查询发票订单信息")
    @RequestMapping(value = "/invoiceOrders", method = RequestMethod.GET)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "invoiceId", value = "发票编号", dataType = "long", paramType = "query")
    })
    public List<AcceptOrderInfoDO> pageList(AcceptOrderInfoVo vo) {
        //登录机构过滤
        UserContext uc = UserContextUtil.getUserContext();
        if (UserType.GENERAL.getType() != uc.getUserType()) {
            vo.setOrgId(uc.getOrgId());
        }
        return acceptOrderInfoService.selectOrderByInvoice(vo);
    }


    @ApiOperation(value = "发票信息下载", notes = "发票信息下载")
    @RequestMapping(value = "/invoice/download", method = RequestMethod.POST)
    public void download(@Validated @RequestBody InvoiceReportQueryVO vo, HttpServletResponse response) throws UnsupportedEncodingException {
        String path = "invoiceOrderReport.xlsx";
        String filename = "发票订单";

        UserContext uc = UserContextUtil.getUserContext();
        if (UserType.GENERAL.getType() != uc.getUserType()) {
            vo.setOrgId(uc.getOrgId());
        }

        List<ListAcceptOrderDO> lists = invoiceInfoService.listInvoiceReportDownload(vo);
        lists.forEach(l -> {
            l.setInvoiceFlagName(InvoiceFlagEnum.getDescByFlag(l.getInvoiceFlag()));
            l.setGuaranteeFeeYuan(StringUtil.toYuan(l.getGuaranteeFee()));
        });
        Map<String, String> map = new HashMap<>();
        map.put("gmtTime", vo.getGuaranteeTimeRange().stream().collect(Collectors.joining(" ~ ")));

        downloadExcelTool.downloadByTemplateName(path, filename, response, lists, map);
    }

}
